
#include "socket.hpp"
#include"Http.hpp"
using namespace socket_ns;
using http_t = std::function<std::string(std::string request)>;

class tcp_server;

class thread_data
{
public:
    thread_data(socket_sptr fd, InetAddr clientaddr, tcp_server *s)
        : _sockfd(fd), _clientaddr(clientaddr), _self(s)
    {
    }

public:
    InetAddr _clientaddr;//结构体包含ip 和 port信息
    socket_sptr _sockfd;//指向mysocket类的指针
    tcp_server *_self; //指向tcp_server 类的指针
};

class tcp_server
{
public:
    //构造函数 通过port 和 io_service_t 对象
    tcp_server(uint16_t port, http_t service)
    :_localaddr("0",port)
    ,_listensock(std::make_unique<tcp_socket>())
    ,_http_service(service)
    ,_runing(false)
    {
        _listensock->build_server_socket(_localaddr);//调用创建服务端套接字
    }
    static void* handlersock(void* args)//线程执行函数
    {
        thread_data* td = static_cast<thread_data*>(args);
        pthread_detach(pthread_self());//线程分离
        std::string request,response;
        int n = td->_sockfd->socked_recv(&request);//读取请求
        if(n > 0)
        {
            response = td->_self->_http_service(request);
            td->_sockfd->socked_send(response);//发送应答
        }
        td->_sockfd->close_sockfd();
        delete td;
        return nullptr;
    }
    void loop()
    {
        _runing = true;
        // 4. 不能直接接受数据，先获取连接
        while (_runing)
        {
            InetAddr peeraddr;
            socket_sptr normalsock = _listensock->accepter(&peeraddr);
            if(normalsock == nullptr) continue;

            pthread_t t;
            thread_data *td = new thread_data(normalsock, peeraddr, this);
            pthread_create(&t, nullptr, handlersock, td); //将线程分离
        }
        _runing = false;
    }
private:
    InetAddr _localaddr;                   // 当地IP 和 port 信息
    std::unique_ptr<mysocket> _listensock; // 指向mysocket类的指针
    bool _runing;                          // 判断是否在运行
    http_t _http_service; // 回调函数
};
